home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
viewers
/
grabsc11
/
grabscrn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-16
|
10KB
|
357 lines
/*****************************************************************************
* Test program for the TSR.ASM module (only in tiny model) *
* Written by Gershon Elber, Sep. 1990 *
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <io.h>
#include "tsr.h"
#define VERSION "1.1"
#define SAVE_FILENAME_RAW "GrScr%03d.raw"
#define SAVE_FILENAME_BAT "GrScr%03d.bat"
#define SAVE_FILENAME_CMAP "GrScr%03d.cmp"
#define SAVE_FILENAME_GIF "GrScr%03d.gif"
#define MAX_LINE_LEN 1024
typedef enum {
NO_DEVICE,
HERCULES,
CGA_LOW,
CGA_HI,
EGA_LOW,
EGA_MED,
VGA_LOW,
VGA_MED,
VGA_HI,
SVGA,
UVGA
} DeviceType;
static int NumOfColors = 16, ColorMask = 15,
DeviceXMax, DeviceYMax, DeviceBase;
static DeviceType Device = NO_DEVICE;
static char *Usage =
"Usage: GrabScrn [-d] Device\t"
"(C) Copyright Gershon Elber, Ver " VERSION ", Sep 1990.\n"
"where: d is one digit {1..8} and Device can be one of:\n"
" HERCULES CGAL CGAH EGAL EGAM VGAL VGAM VGAH SVGA UVGA.\n";
static unsigned char ScanLine[MAX_LINE_LEN];
static void GetScanLine(unsigned char *ScanLine, int Y);
static void TsrFunc(void);
/******************************************************************************
* main - set and install the screen grabber. *
******************************************************************************/
void main(int argc, char **argv)
{
int far *n;
DeviceType far *d;
NumOfColors = 16;
if (argc > 2) {
if (argv[1][0] == '-' &&
argv[1][1] >= '1' && argv[1][1] <= '8') {
/* -digit detected: force the number of colors to use. */
NumOfColors = 2 << (argv[1][1] - '1');
argc--;
argv++;
}
else {
fprintf(stderr, "Syntax error.\n");
fprintf(stderr, Usage);
exit(2);
}
}
if (argc != 2) {
fprintf(stderr, Usage);
exit(1);
}
if (strlen(argv[1]) < 4)
argv[1][4] = 0; /* Trim the Device to 4 characters. */
if (strcmp(argv[1], "HERC") == 0) {
Device = HERCULES;
NumOfColors = 2;
}
else if (strcmp(argv[1], "CGAL") == 0) {
Device = CGA_LOW;
NumOfColors = 4;
}
else if (strcmp(argv[1], "CGAH") == 0) {
Device = CGA_HI;
NumOfColors = 2;
}
else if (strcmp(argv[1], "EGAL") == 0) {
Device = EGA_LOW;
}
else if (strcmp(argv[1], "EGAM") == 0) {
Device = EGA_MED;
}
else if (strcmp(argv[1], "VGAL") == 0) {
Device = VGA_LOW;
}
else if (strcmp(argv[1], "VGAM") == 0) {
Device = VGA_MED;
}
else if (strcmp(argv[1], "VGAH") == 0) {
Device = VGA_HI;
}
else if (strcmp(argv[1], "SVGA") == 0) {
Device = SVGA;
}
else if (strcmp(argv[1], "UVGA") == 0) {
Device = UVGA;
}
else {
fprintf(stderr, "Undefined device type \"%s\".\n", argv[1]);
fprintf(stderr, Usage);
exit(2);
}
switch (HookKbdInterrupt(TsrFunc, 0x4408 /* ALT F10 */)) {
case 0:
fprintf(stderr, "GrabScrn is installed, ALT-F10 To activate.\n");
keep(0, 0x400);
break;
case 1:
fprintf(stderr,
"GrabScrn is already installed, device set to \"%s\", %d Colors.\n",
argv[1], NumOfColors);
d = MK_FP(InstalledTSRSegment, &Device);
*d = Device;
n = MK_FP(InstalledTSRSegment, &NumOfColors);
*n = NumOfColors;
break;
case 2:
fprintf(stderr, "GrabScrn failed to install.\n");
break;
}
}
/******************************************************************************
* Set device parameters. *
******************************************************************************/
static void SetDeviceParams(void)
{
switch (Device) {
case HERCULES:
DeviceYMax = 350;
DeviceXMax = 720;
DeviceBase = 0xb000;
break;
case CGA_LOW:
DeviceYMax = 200;
DeviceXMax = 320;
DeviceBase = 0xb800;
break;
case CGA_HI:
DeviceYMax = 200;
DeviceXMax = 640;
DeviceBase = 0xb800;
break;
case EGA_LOW:
DeviceYMax = 200;
DeviceXMax = 640;
DeviceBase = 0xa000;
break;
case EGA_MED:
DeviceYMax = 350;
DeviceXMax = 640;
DeviceBase = 0xa000;
break;
case VGA_LOW:
DeviceYMax = 200;
DeviceXMax = 640;
DeviceBase = 0xa000;
break;
case VGA_MED:
DeviceYMax = 350;
DeviceXMax = 640;
DeviceBase = 0xa000;
break;
case VGA_HI:
DeviceYMax = 480;
DeviceXMax = 640;
DeviceBase = 0xa000;
break;
case SVGA:
DeviceYMax = 600;
DeviceXMax = 800;
DeviceBase = 0xa000;
break;
case UVGA:
DeviceYMax = 768;
DeviceXMax = 1024;
DeviceBase = 0xa000;
break;
}
ColorMask = NumOfColors - 1;
}
/******************************************************************************
* Update the given scan line buffer with the pixel levels of the Y line. *
* This routine is device specific, so make sure you know was you are doing *
******************************************************************************/
static void GetScanLine(unsigned char *ScanLine, int Y)
{
unsigned char DeviceByte;
int i, j, k;
unsigned int DeviceOffset, Bit;
union REGS InRegs, OutRegs;
switch (Device) {
case HERCULES:
DeviceOffset = 0x2000 * (Y % 4) + (Y / 4) * (DeviceXMax / 8);
/* In one scan lines we have DeviceXMax / 8 bytes: */
for (i = 0, k = 0; i < DeviceXMax / 8; i++) {
DeviceByte = (unsigned char) peekb(DeviceBase, DeviceOffset++);
for (j = 0, Bit = 0x80; j < 8; j++) {
ScanLine[k++] = (DeviceByte & Bit ? 1 : 0);
Bit >>= 1;
}
}
break;
case CGA_LOW:
case CGA_HI:
case EGA_LOW:
case EGA_MED:
case VGA_LOW:
case VGA_MED:
case VGA_HI:
case SVGA:
case UVGA:
InRegs.x.dx = Y;
InRegs.h.bh = 0;
InRegs.h.ah = 0x0d; /* BIOS Read dot. */
for (i = 0; i < DeviceXMax; i++) {
InRegs.x.cx = i;
int86(0x10, &InRegs, &OutRegs);
ScanLine[i] = OutRegs.h.al & ColorMask;
}
/* Mark this line as done by putting a xored dot on the left. */
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor with color 1. */
InRegs.x.cx = 0;
InRegs.x.dx = Y;
int86(0x10, &InRegs, &OutRegs);
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor with color 1. */
InRegs.x.cx = 1;
InRegs.x.dx = Y;
int86(0x10, &InRegs, &OutRegs);
if (Y == DeviceYMax - 1) {/* Last row - clear all marks we made. */
for (i = 0; i < DeviceYMax; i++) {
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor back with color 1. */
InRegs.x.cx = 0;
InRegs.x.dx = i;
int86(0x10, &InRegs, &OutRegs);
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor back with color 1. */
InRegs.x.cx = 1;
InRegs.x.dx = i;
int86(0x10, &InRegs, &OutRegs);
}
}
break;
default:
break;
}
}
/******************************************************************************
* Function to save the current color map and a batch file that should be *
* invoked to create a gif image out of the raw data saved. *
******************************************************************************/
static void SaveColorMap(int FileNumber)
{
char FileName[20];
int i, Handle;
union REGS InRegs, OutRegs;
sprintf(FileName, SAVE_FILENAME_CMAP, FileNumber);
if ((Handle = _creat(FileName, 0)) != -1) {
if (Device == HERCULES || Device == CGA_HI) {
/* Black and White color map. */
_write(Handle, "1 0 0 0\r\n", 15);
_write(Handle, "2 255 255 255\r\n", 15);
}
else if (Device == CGA_LOW) {
/* 4 color map (palette 1 only). */
_write(Handle, "1 0 0 0\r\n", 15);
_write(Handle, "2 0 255 0\r\n", 15);
_write(Handle, "3 255 0 0\r\n", 15);
_write(Handle, "4 0 255 255\r\n", 15);
}
else {
for (i = 0; i < NumOfColors; i++) {
InRegs.h.bl = i;
InRegs.x.ax = 0x1015;
int86(0x10, &InRegs, &OutRegs);
sprintf(ScanLine, "%3d %4d %4d %4d\r\n",
i + 1,
OutRegs.h.dh << 2, OutRegs.h.ch << 2, OutRegs.h.cl << 2);
_write(Handle, ScanLine, strlen(ScanLine));
}
}
_close(Handle);
}
sprintf(FileName, SAVE_FILENAME_BAT, FileNumber);
if ((Handle = _creat(FileName, 0)) != -1) {
sprintf(ScanLine, "raw2gif -s %d %d -p "
SAVE_FILENAME_CMAP " "
SAVE_FILENAME_RAW " > "
SAVE_FILENAME_GIF "\r\n",
DeviceXMax, DeviceYMax,
FileNumber, FileNumber, FileNumber);
_write(Handle, ScanLine, strlen(ScanLine));
sprintf(ScanLine, "del "
SAVE_FILENAME_CMAP "\r\ndel "
SAVE_FILENAME_RAW "\r\n",
FileNumber, FileNumber);
_write(Handle, ScanLine, strlen(ScanLine));
_close(Handle);
}
}
/******************************************************************************
* This is the function get invoked when TSR gets activated. *
******************************************************************************/
static void TsrFunc(void)
{
static int FileNumber = 1;
char FileName[20];
int i, Handle;
SetDeviceParams();
SaveColorMap(FileNumber);
sprintf(FileName, SAVE_FILENAME_RAW, FileNumber++);
if ((Handle = _creat(FileName, 0)) != -1) {
for (i = 0; i < DeviceYMax; i++) {
GetScanLine(ScanLine, i);
_write(Handle, ScanLine, DeviceXMax);
}
_close(Handle);
}
}